#include "main.h"
#include "stmflash.h"
#include "db_wdg.h"        
#include "crc32.h"    

/**
* @brief USART1 interrupt service function
* @param
*    none
*    
* @return none
*/
void USART1_IRQHandler(void)
{
    if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) 
    { 
        usart3_buf[usart3_cnt++]=USART_ReceiveData(USART1);    //串口1 接收数据直接放到数组3，由串口3处理
        if(usart3_cnt>=200)
        {
            usart3_cnt=0;
        }
        USART_ClearITPendingBit(USART1, USART_IT_RXNE);        //清除串口接受完成标志
    }
    if(USART_GetITStatus(USART1, USART_IT_TC) != RESET) 
    {
        uart1_send_cnt++;
        if(uart1_send_cnt >= uart1_send_length)        //结束中断发送
        {
            uart1_send_length=0;
            uart1_send_cnt=0;
            send_busy1=0;
        }
        else
        {
            send_busy1=1;        //发送忙
            USART_SendData(USART1, uart1_send_buf[uart1_send_cnt]);
        }
        USART_ClearITPendingBit(USART1, USART_IT_TC);        //清除串口接受完成标志
    }
}

/**
* @brief USART3 interrupt service function
* @param
*    none
*    
* @return none
*/
void USART3_IRQHandler(void)
{
    u8 char_data=0;
    if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET) 
    { 
        char_data=USART_ReceiveData(USART3);
        usart3_buf[usart3_cnt++]=char_data;
        USART_SendData(USART1, char_data);
        if(usart3_cnt>=200)
        {
            usart3_cnt=0;
        }
        USART_ClearITPendingBit(USART3, USART_IT_RXNE);        //清除串口接受完成标志
    }
    if(USART_GetITStatus(USART3, USART_IT_TC) != RESET) 
    {
        uart3_send_cnt++;
        if(uart3_send_cnt >= uart3_send_length)        //结束中断发送
        {
            uart3_send_length=0;
            uart3_send_cnt=0;
            send_busy3=0;
        }
        else
        {
            send_busy3=1;        //发送忙
            USART_SendData(USART3, uart3_send_buf[uart3_send_cnt]);
        }
        USART_ClearITPendingBit(USART3, USART_IT_TC);        //清除串口接受完成标志
    }
}

/**
* @brief USART1 initialization
* @param
*    bound : Baud rate
*    
* @return none 
*/
void usart1_init(u32 bound)
{
    //GPIO端口设置
    GPIO_InitTypeDef GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;
 
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);    //时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);    //时钟    
    
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; 
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;    //复用推挽输出
    GPIO_Init(GPIOA, &GPIO_InitStructure);
   
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
    GPIO_Init(GPIOA, &GPIO_InitStructure);  

   //Usart1 NVIC 配置

    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0 ;//抢占优先级0
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;        //子优先级0
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;            //IRQ通道使能
    NVIC_Init(&NVIC_InitStructure);    //根据指定的参数初始化VIC寄存器

    //USART1 初始化设置

    USART_InitStructure.USART_BaudRate = bound;//一般设置为9600;
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
    USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位
    USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;    //收发模式

    USART_Init(USART1, &USART_InitStructure); //初始化串口
    
    USART_ClearITPendingBit(USART1, USART_IT_RXNE);        //清除串口接受完成标志    
    USART_ClearITPendingBit(USART1, USART_IT_TC);        //清除串口接受完成标志    
    
    USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启接收中断
    
    USART_ITConfig(USART1, USART_IT_TC, ENABLE);//开启中断
    USART_Cmd(USART1, ENABLE);                    //使能串口 
}
/**
* @brief USART3 initialization
* @param
*    bound : Baud rate
*    
* @return none 
*/
void usart3_init(u32 bound)
{
    //GPIO端口设置
    GPIO_InitTypeDef GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;
 
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);    //时钟
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);    //时钟    
    
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; 
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;    //复用推挽输出
    GPIO_Init(GPIOB, &GPIO_InitStructure);
   
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
    GPIO_Init(GPIOB, &GPIO_InitStructure);  

   //Usart3 NVIC 配置

    NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0 ;//抢占优先级0
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;        //子优先级0
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;            //IRQ通道使能
    NVIC_Init(&NVIC_InitStructure);    //根据指定的参数初始化VIC寄存器

    //USART3 初始化设置

    USART_InitStructure.USART_BaudRate = bound;//一般设置为9600;
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
    USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位
    USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;    //收发模式

    USART_Init(USART3, &USART_InitStructure); //初始化串口
    
    USART_ClearITPendingBit(USART3, USART_IT_RXNE);        //清除串口接受完成标志    
    USART_ClearITPendingBit(USART3, USART_IT_TC);        //清除串口接受完成标志    
    
    USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);//开启接收中断
    
    USART_ITConfig(USART3, USART_IT_TC, ENABLE);//开启中断
    USART_Cmd(USART3, ENABLE);                    //使能串口 
}


/**
* @brief USART3 send a byte
* @param
*    byte : send data
*    
* @return none 
*/
void usart3_send_byte(unsigned char byte)   
{
    uint16_t time_out3=0;
    USART_SendData(USART3, byte);      
    while( USART_GetFlagStatus(USART3,USART_FLAG_TC)!= SET)
    {
        time_out3++;
        if(time_out3>=20000)
        {
            time_out3=0;
            break;
        }
    }                
}

/**
* @brief USART1 send string
* @param
*    *s : string
*    num: number of send byte
* @return none 
*/
void usart1_send_string(u8 *s,u16 num)        //串口1
{
    u16 i=0;
    send_busy1=1;
    uart1_send_length=num;        
    for(i=0;i<num;i++)
    {
        uart1_send_buf[i]=s[i];        //数组赋值
    }
    USART_SendData(USART1, uart1_send_buf[0]);  //发送首字节，由发送中断自动发送
}

/**
* @brief USART3 send string
* @param
*    *s : string
*    num: number of send byte
* @return none 
*/
void usart3_send_string(u8 *s, u16 num)        //串口3
{
    u16 i=0;
    send_busy3=1;
    uart3_send_length=num;        
    for(i=0;i<num;i++)
    {
        uart3_send_buf[i]=s[i];        //数组赋值
    }
    USART_SendData(USART3, uart3_send_buf[0]);  //发送首字节，由发送中断自动发送
}
/**
* @brief return bluetooth
* @param
*    
*    
* @return none 
*/
void return_data(u8 *pbuff,u8 length,u8 cmd)
{
    u8 i=0;
    u32 crc_data=0;

    usart3_tx_buf[tx3_buf_cnt][0]=0x68;        //数据头
    usart3_tx_buf[tx3_buf_cnt][1]=cmd;         //命令号
    usart3_tx_buf[tx3_buf_cnt][2]=length;      //数据长度
    for(i=0;i<length;i++)
    {
        usart3_tx_buf[tx3_buf_cnt][3+i]=pbuff[i];
    }
//    //计算校验
//    CRC_ResetDR();
//    crc_data=CRC_CalcBlockCRC(usart3_tx_buf[tx3_buf_cnt],length+3);    //计算校验和,高字节保存在高地址
    crc_data=crc32( usart3_tx_buf[tx3_buf_cnt],length+3);
    usart3_tx_buf[tx3_buf_cnt][length+3]=crc_data&0x000000ff;
    usart3_tx_buf[tx3_buf_cnt][length+4]=(crc_data>>8)&0x000000ff;
    usart3_tx_buf[tx3_buf_cnt][length+5]=(crc_data>>16)&0x000000ff;
    usart3_tx_buf[tx3_buf_cnt][length+6]=(crc_data>>24)&0x000000ff;
    usart3_tx_buf[tx3_buf_cnt][length+7]=0x0000007E;       //数据尾
    usart1_send_string(usart3_tx_buf[tx3_buf_cnt],length+8);        //发送数据到串口
    tx3_flag[tx3_buf_cnt]=1;tx3_length[tx3_buf_cnt]=length+8;    tx3_buf_cnt++;    if(tx3_buf_cnt>=4)    tx3_buf_cnt=0;  //发送数据到串口3
 
}
/**
* @brief USART3 processing
* @param
*    
*    
* @return none 
*/
void deal_usart3(void)
{
    u16 i=0;
    u8 ret_ok=0;
    u8 time[6]={0};
    u8 save_flag=0;     //需要保存数据
    u32 crc_data=0;
    u8 data_length=0;       //数据长度
    if(usart3_buf[0]==0x68)       //数据头正确
    {
        data_length=usart3_buf[2];      //数据长度
        if(usart3_buf[data_length+7] == 0x7E) //数据尾
        {
//            CRC_ResetDR();
//            crc_data=CRC_CalcBlockCRC(usart3_buf,data_length+3);    //计算校验和,高字节保存在高地址
            crc_data=crc32(usart3_buf,data_length+3);
            if(usart3_buf[data_length+6]==crc_data>>24 && usart3_buf[data_length+5]==((crc_data>>16)&0x000000ff)
               && usart3_buf[data_length+4]==((crc_data>>8)&0x000000ff) && usart3_buf[data_length+3]==(crc_data&0x000000ff))        //校验正确
            {
                if(usart3_buf[1] == 0)     //升级文件内容
                {
                    ret_ok=1;
                }
                else if(usart3_buf[1] == 0x01) //升级文件内容
                {
                    ret_ok=1;
                }
                else if(usart3_buf[1] == 0x02) //查询版本信息
                {
                    ret_ok=1;
                }
                else if(usart3_buf[1] == 0x03) //设置本机时间
                {
                    ret_ok=1;
                    //年月日时分秒
                    for(i=0;i<6;i++)
                    {
                        time[i]=usart3_buf[3+i];
                    }
                    RTC_Set(time[0]+2000,time[1],time[2],time[3],time[4],time[5]);
                }
                else if(usart3_buf[1] == 0x04) //设置启动关闭时间
                {
                    ret_ok=1;
                    sys_mode=0;
                    //时分秒
                    for(i=0;i<6;i++)
                    {
                        if(usart3_buf[3+i*6] !=0xff)
                        {
                            //启动时间
                             relay.start_time[i][3]=usart3_buf[3+i*6];
                             relay.start_time[i][4]=usart3_buf[4+i*6];
                             relay.start_time[i][5]=usart3_buf[5+i*6];
                            //关闭时间
                             relay.over_time[i][3]=usart3_buf[6+i*6];
                             relay.over_time[i][4]=usart3_buf[7+i*6];
                             relay.over_time[i][5]=usart3_buf[8+i*6];
                             relay.relay_switch[i]=0;
                        }
                    }
                    save_flag=1;
                }
                else if(usart3_buf[1] == 0x05) //调试继电器
                {
                     ret_ok=1;
                     sys_mode=1;
                    //每个继电器由两个字节控制,第一个字节为开启使能为1开启，第二个字节为关闭使能为1关闭
                    for(i=0;i<6;i++)
                    {
                        if(usart3_buf[3+i*2])
                        {
                              relay.relay_switch[i]=1;      //开启继电器
                        }
                        if(usart3_buf[4+i*2])
                        {
                              relay.relay_switch[i]=0;      //关闭继电器
                        }
                    }
                }
                else if(usart3_buf[1] == 0x06) //读取本机时间和设定时间
                {
                    return_time();
                }
                else if(usart3_buf[1] == 0x07) //修改蓝牙名称
                {
//                    ret_ok=1;
                    for(i=0;i<data_length;i++)
                    {
                        bluetooth_name[i]=usart3_buf[3+i];
                    }
                    name_length=data_length; 
                    for(i=name_length;i<20;i++)
                    {
                        bluetooth_name[i]=0;    //每次存储前把后面数据清除
                    }
                    set_name(bluetooth_name,name_length);
                    save_flag=1;
                    
                }
                else if(usart3_buf[1] == 0x08) //读取蓝牙名称
                {
                     return_data(bluetooth_name,20,0x08);       
                }
                else if(usart3_buf[1] == 0x09) //读取继电器状态
                {
                    return_relay();     //返回继电器状态
                }
                    
            }
            if(ret_ok)
            {
                usart1_send_string((u8 *)"BT+OK\r\n",7);
                usart3_send_string((u8 *)"BT+OK\r\n",7); //返回ok
            }
            //保存数据
            if(save_flag)
            {
                save_flag=0;
                save_all_data();    //保存数据
            }
        }
    }
    for(i=0;i<rec3_length;i++)
    {
        usart3_buf[i]=0;
    }
}
/**
* @brief reset bluetooth name
* @param
*    *p:name string
*    length:name length
* @return none 
*/
void set_name(u8 *p,u8 length)
{
    u8 i=0;
    usart3_tx_buf[tx3_buf_cnt][0]='A';
    usart3_tx_buf[tx3_buf_cnt][1]='T';
    usart3_tx_buf[tx3_buf_cnt][2]='+';
    usart3_tx_buf[tx3_buf_cnt][3]='N';
    usart3_tx_buf[tx3_buf_cnt][4]='A';
    usart3_tx_buf[tx3_buf_cnt][5]='M';
    usart3_tx_buf[tx3_buf_cnt][6]='E';
    usart3_tx_buf[tx3_buf_cnt][7]='=';
    for(i=0;i<length;i++)
    {
        usart3_tx_buf[tx3_buf_cnt][8+i]=p[i];
    }
    usart3_tx_buf[tx3_buf_cnt][8+length]='\r';
    usart3_tx_buf[tx3_buf_cnt][9+length]='\n';
    
    usart1_send_string(usart3_tx_buf[tx3_buf_cnt],10+length);        //发送数据到串口232
    tx3_flag[tx3_buf_cnt]=1;tx3_length[tx3_buf_cnt]=10+length;    tx3_buf_cnt++;    if(tx3_buf_cnt>=4)    tx3_buf_cnt=0;  //发送数据到串口3 ttl
}

/**
* @brief Return to current time and setting time
* @param
*    
*    
* @return none 
*/
void return_time(void)
{
    u8 i=0;
    u8 buf_time[100]={0};
    buf_time[0]=Year;
    buf_time[1]=Month;
    buf_time[2]=Day;
    buf_time[3]=Hour;
    buf_time[4]=Minute;
    buf_time[5]=Second;
    
    for(i=0;i<6;i++)
    {
        //启动时间
        buf_time[6+i*6]=relay.start_time[i][3];
        buf_time[7+i*6]=relay.start_time[i][4];
        buf_time[8+i*6]=relay.start_time[i][5];
        //关闭时间
        buf_time[9+i*6]= relay.over_time[i][3];
        buf_time[10+i*6]=relay.over_time[i][4];
        buf_time[11+i*6]=relay.over_time[i][5];
    }
    return_data(buf_time,42,0x06);       //返回数据
}
/**
* @brief Return relay states
* @param
*    
*    
* @return none 
*/
void return_relay(void)
{
    u8 i=0;
    u8 buf_relay[6]={0};
    for(i=0;i<6;i++)
    {
        buf_relay[i]=relay.relay_switch[i];
    }
    return_data(buf_relay,6,0x09);       //返回数据
}

/**
* @brief Calculation of CRC
* @param
*    arr_buff:data buffer
*    
* @return crc16
*/
unsigned int CRC16( unsigned char *arr_buff, unsigned char len)  
{
    unsigned int  crc=0xFFFF;
    unsigned char i, j;
    for ( j=0;j<len;j++)
    {
        crc=crc^*(arr_buff+j);
        for ( i=0; i<8; i++)
        {
            if ((crc&0x0001)>0)
            {
                crc>>=1;
                crc^=0xa001;
            }
            else
                crc>>=1;            
        }
    }
    return  (crc);
}



/**
* @brief send data to usart3
* @param
*    
*    
* @return none 
*/
void send_to_bluetooth(void)
{    
    if(!send_busy3)    
    {
        if(tx3_flag[send3_scan_cnt])   //发送缓冲区有数据
        {
            usart3_send_string((u8 *)usart3_tx_buf[send3_scan_cnt], tx3_length[send3_scan_cnt]);    //中断发送
            tx3_flag[send3_scan_cnt] = 0;
            tx3_length[send3_scan_cnt] = 0;
        }
    }
    send3_scan_cnt++;
    if(send3_scan_cnt >= 4)
    {
        send3_scan_cnt=0;
    }
}

